bitkeeper revision 1.1071.1.2 (40f3eed8kdZ959gB_ZYkHRPFFEGkKg)
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Tue, 13 Jul 2004 14:16:56 +0000 (14:16 +0000)
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Tue, 13 Jul 2004 14:16:56 +0000 (14:16 +0000)
Fix domain death to stop all CPUs running over the defunct page tables.

xen/arch/x86/domain.c
xen/arch/x86/x86_32/mm.c
xen/common/kernel.c
xen/include/asm-x86/mm.h

index 5d8fd069803a1e544550acbee20bb00cc8c0698b..83eea289aa2232b2d435b675536031fe136e9407 100644 (file)
@@ -445,12 +445,8 @@ void domain_relinquish_memory(struct domain *d)
     struct pfn_info  *page;
     unsigned long     x, y;
 
-    /*
-     * If we're executing the idle task then we may still be running over the 
-     * dead domain's page tables. We'd better fix that before freeing them!
-     */
-    if ( is_idle_task(current) )
-        write_ptbase(&current->mm);
+    /* Ensure that noone is running over the dead domain's page tables. */
+    synchronise_pagetables(~0UL);
 
     /* Exit shadow mode before deconstructing final guest page table. */
     shadow_mode_disable(d);
index d034240b4129af7b0de7bbc6de408245357bcf4e..d350689071c4645436a6886327665735d10c17f3 100644 (file)
@@ -129,6 +129,22 @@ void __init zap_low_mappings(void)
 }
 
 
+/*
+ * Allows shooting down of borrowed page-table use on specific CPUs.
+ * Specifically, we borrow page tables when running the idle domain.
+ */
+static void __synchronise_pagetables(void *mask)
+{
+    struct domain *d = current;
+    if ( ((unsigned long)mask & (1<<d->processor)) && is_idle_task(d) )
+        write_ptbase(&d->mm);
+}
+void synchronise_pagetables(unsigned long cpu_mask)
+{
+    __synchronise_pagetables((void *)cpu_mask);
+    smp_call_function(__synchronise_pagetables, (void *)cpu_mask, 1, 1);
+}
+
 long do_stack_switch(unsigned long ss, unsigned long esp)
 {
     int nr = smp_processor_id();
index 2f99bbee434e5bf83877bd768e629ceeb497292a..a2fbd45dac2a6a98b8a21baad0bd85951d0986e6 100644 (file)
@@ -225,7 +225,6 @@ void cmain(unsigned long magic, multiboot_info_t *mbi)
 
     init_frametable((void *)FRAMETABLE_VIRT_START, max_page);
 
-
 #elif defined(__x86_64__)
 
     init_frametable(__va(xenheap_phys_end), max_page);
index 0586562c626f06962bacc98c4e7691e49f0b2a93..b8a4c5e496c80a5eb9387a937f10d0c4e902256c 100644 (file)
@@ -276,6 +276,12 @@ static inline int get_page_and_type(struct pfn_info *page,
 
 int check_descriptor(unsigned long a, unsigned long b);
 
+/*
+ * Use currently-executing domain's pagetables on the specified CPUs.
+ * i.e., stop borrowing someone else's tables if you are the idle domain.
+ */
+void synchronise_pagetables(unsigned long cpu_mask);
+
 /*
  * The MPT (machine->physical mapping table) is an array of word-sized
  * values, indexed on machine frame number. It is expected that guest OSes